package com.shelpe.services.sinbad.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shelpe.services.sinbad.dao.RptKeywordMapper;
import com.shelpe.services.sinbad.model.KeywordExample;
import com.shelpe.services.sinbad.model.RptKeyword;
import com.shelpe.services.sinbad.model.RptKeywordExample;
import com.shelpe.services.sinbad.model.RptKeywordExample.Criteria;
import com.shelpe.services.sinbad.model.RptKeywordParam;
import com.shelpe.services.sinbad.service.RptKeywordService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class RptKeywordServiceImpl implements RptKeywordService{

	private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
	
	@Autowired
	RptKeywordMapper rptKeywordMapper;

	@Override
	public List<RptKeyword> selectAll(Long userId) {
		RptKeywordExample example = new RptKeywordExample();
		example.setUserId(userId);
		return rptKeywordMapper.selectByExample(example);
	}

	@Override
	public List<RptKeyword> select(Long keywordId, Long adgroupId, Long campaignId, Long userId){
		RptKeywordExample example = new RptKeywordExample();
		example.setUserId(userId);
		example.createCriteria().andKeywordIdEqualTo(keywordId)
		.andAdgroupIdEqualTo(adgroupId).andCampaignIdEqualTo(campaignId);
		return rptKeywordMapper.selectByExample(example);
	}
	
	@Override
	public RptKeyword selectSum(RptKeywordParam param) {
		return rptKeywordMapper.selectSumByExample(paramToExample(param));
	}
	
	@Override
	public List<KeywordCompositeID> getKeywordIds(RptKeywordParam param) {
		log.debug("getKeywordIds param:{}", param.toString());
		long start = System.currentTimeMillis();
		Set<Long> keywordIds = new HashSet<Long>();
		List<KeywordCompositeID> ids = new ArrayList<KeywordCompositeID>();
		if(param.getImpressionsDay() > 0){
			//根据展现量查询
			param.setDay(param.getImpressionsDay());
			List<RptKeyword> words = rptKeywordMapper.selectImpressionsByExample(paramToExample(param));
			for(RptKeyword rpt : words){
				if(rpt.getImpressions()==0){
					if(keywordIds.add(rpt.getKeywordId())){
						ids.add(new KeywordCompositeID(rpt.getKeywordId(), rpt.getCampaignId(), 0));
					}
				}
			}
			log.info("select by impression cost {} ms", System.currentTimeMillis() - start, param);
			start = System.currentTimeMillis();
		}
		if(param.getClickDay() > 0){
			//根据点击量查询
			param.setDay(param.getClickDay());
			List<RptKeyword> words = rptKeywordMapper.selectClickByExample(paramToExample(param));
			for(RptKeyword rpt : words){
				if(rpt.getImpressions()>1000&&rpt.getClick()<1){
					if(keywordIds.add(rpt.getKeywordId())){
						ids.add(new KeywordCompositeID(rpt.getKeywordId(), rpt.getCampaignId(), 0));
					}
				}
			}
			log.info("select by click cost {} ms", System.currentTimeMillis() - start, param);
			start = System.currentTimeMillis();
		}
		if(param.getQscore() > 0 || param.getMobileQscore() > 0){
			param.setDay(1);
			param.setSource((byte)23);
			
			RptKeywordExample example = paramToExample(param);
			Criteria criteria = example.getOredCriteria().get(0);
			criteria.andQscoreLessThan(param.getQscore());
			
			RptKeywordExample mexample = paramToExample(param);
			Criteria mcriteria = mexample.getOredCriteria().get(0);
			mcriteria.andWirelessQscoreLessThan(param.getMobileQscore());
			
			example.or(mcriteria);
			List<RptKeyword> words = rptKeywordMapper.selectQscoreByExample(example);
			for(RptKeyword rpt : words){
				if(keywordIds.add(rpt.getKeywordId())){
					ids.add(new KeywordCompositeID(rpt.getKeywordId(), rpt.getCampaignId(), 0));
				}
			}
			
			log.info("select by qscore cost {} ms", System.currentTimeMillis() - start, param);
			start = System.currentTimeMillis();
		} 
		return ids;
	}
	
	@Override
	public Float getAvgCtr(RptKeywordParam param){
		Float ret = 0f;
		Map<Long, Float> avgCtrs = rptKeywordMapper.selectAvgCtrByExample(paramToExample(param));
		if(avgCtrs!=null){
			if(avgCtrs.containsKey(param.getAdgroupId())){
				ret = avgCtrs.get(param.getAdgroupId());
			}
		}
		return ret;
	}
	
	@Override
	public RptKeyword getCtrAndRoi(RptKeywordParam param){
		List<RptKeyword> ctrs = rptKeywordMapper.selectCtrRoiByExample(paramToExample(param));
		if(ctrs!=null){
			return ctrs.size()>0?ctrs.get(0):null;
		}else{
			return null;
		}
	}

	@Override
	public RptKeyword getSummariesMetric(RptKeywordParam param) {
		log.info("getSummariesMetric param:{}", param.toString());
		return rptKeywordMapper.selectSummariesMetric(paramToExample(param));
	}

	@Override
	public List<RptKeyword> getReportsTrend(RptKeywordParam param) {
		log.info("getReportsTrend param:{}", param.toString());
		List<RptKeyword> retList = null;
		if(param.getAdgroupId()!=null){//以关键词分组
			log.info("getReportsTrend group by keyword");
			retList = rptKeywordMapper.selectReportsTrendByAdgroupId(paramToExample(param));
		}else if(param.getCampaignId()!=null){//以推广组分组
			log.info("getReportsTrend group by adgroupId");
			retList = rptKeywordMapper.selectReportsTrendByCampaignId(paramToExample(param));
		}else{
			log.info("getReportsTrend  group by campaignId");
			retList = rptKeywordMapper.selectReportsTrendByUserId(paramToExample(param));
		}
		return retList;
	}
	
	@Override
	public List<RptKeyword> getReportsTrendByDate(RptKeywordParam param) {
		log.info("getReportsTrendByDate param:{}", param.toString());
		List<RptKeyword> retList = null;
		retList = rptKeywordMapper.selectReportsTrendByDate(paramToExample(param));
		return retList;
	}
	
	@Override
	public int delete(Long userId, String keywordIds) {
		RptKeywordExample example = new RptKeywordExample();
		example.setUserId(userId);
		example.createCriteria().andKeywordIdIn(toLongList(keywordIds));
		return rptKeywordMapper.deleteByExample(example);
	}

	private List<Long> toLongList(String params){
		List<Long> values = new ArrayList<Long>();
		for(String param : params.split(",")){
			values.add(Long.valueOf(param.trim()));
		}
		return values;
	}

	
	private RptKeywordExample paramToExample(RptKeywordParam param){
		RptKeywordExample example = new RptKeywordExample();
		example.setUserId(param.getUserId());
		Date date = getDate(0-param.getDay());
		Criteria criteria = example.createCriteria();
		
		if(!(param.getStartDate()==null||param.getEndDate()==null)){
			try {
				criteria.andDateBetween(SDF.parse(param.getStartDate()), SDF.parse(param.getEndDate()));
			} catch (ParseException e) {
				log.error("RptKeywordExample paramToExample date parse:{}", e.getMessage());
			}
		}else{
			criteria.andDateGreaterThanOrEqualTo(date);
		}
		
		if(param.getKeywordId()!=null){
			criteria.andKeywordIdEqualTo(param.getKeywordId());
		}
		
		if(param.getKeywordIds()!=null){
			criteria.andKeywordIdIn(param.getKeywordIds());
		}

		if(param.getAdgroupId()!=null){
			criteria.andAdgroupIdEqualTo(param.getAdgroupId());
		}
		
		if(param.getCampaignId()!=null){
			criteria.andCampaignIdEqualTo(param.getCampaignId());
		}
		
		if(param.getCampaignIds() != null){
			criteria.andCampaignIdIn(param.getCampaignIds());
		}
		
		if(param.getSource()!=null){
			switch (param.getSource()) {
			case 1://mobile
				criteria.andSourceBetween((byte)4, (byte)5);
				break;
			case 2://pc
				criteria.andSourceBetween((byte)1, (byte)2);
				break;
			case 3://获取质量得分
				criteria.andSourceEqualTo((byte)23);
				break;
			}
		}
		return example;
	}
	
	private Date getDate(int amount){
		return getDate(new Date(), amount);
	}
	
	private Date getDate(Date date, int amount){
		Calendar calendar = Calendar.getInstance();
		if(date != null){
			calendar.setTime(date);
		}
		calendar.add(Calendar.DAY_OF_MONTH, amount);
		return calendar.getTime();
	}

}
